import { App } from "vue";
import {
  createRouter,
  createWebHashHistory,
  NavigationGuardNext,
  RouteLocationNormalized,
  Router,
  RouteRecordRaw
} from "vue-router";
import { IMenu } from "../pinia/interface";
import NProgress from "../progress";

const modules = import.meta.glob("@/views/**/index.vue");
export class BaseRouter {
  router: Router;
  private isAdd = false;

  initRouter() {
    this.createRouter();
    this.setLogin();
    this.setHome();
    this.set403404Route();
    this.beforeEach();
    this.afterEach();
  }

  private setHome() {
    console.log("我们还没有首页oooo!!");
  }

  private setLogin() {
    this.router.addRoute({
      path: "/login",
      name: "Login",
      component: () => import("@/views/login/index.vue"),
      meta: {
        title: "登录",
        showLink: false,
        rank: 101
      }
    });
  }

  private set403404Route() {
    this.router.addRoute({
      path: "/error",
      redirect: "/error/403",
      meta: {
        icon: "informationLine",
        title: "异常页面",
        // showLink: false,
        rank: 9
      },
      children: [
        {
          path: "/error/403",
          name: "403",
          component: () => import("@/views/error/403.vue"),
          meta: {
            title: "403"
          }
        },
        {
          path: "/error/404",
          name: "404",
          component: () => import("@/views/error/404.vue"),
          meta: {
            title: "404"
          }
        },
        {
          path: "/error/500",
          name: "500",
          component: () => import("@/views/error/500.vue"),
          meta: {
            title: "500"
          }
        }
      ]
    });
  }

  createRouter() {
    if (!this.router) {
      this.router = createRouter({
        history: createWebHashHistory(),
        routes: [
          {
            path: "/redirect",
            component: import("@/layouts/backstage/index.vue"),
            meta: {
              title: "加载中...",
              showLink: false,
              rank: 102
            },
            children: [
              {
                path: "/redirect/:path(.*)",
                name: "Redirect",
                component: () => import("@/layouts/backstage/redirect.vue")
              }
            ]
          }
        ],
        strict: true,
        scrollBehavior(to, from, savedPosition) {
          return new Promise(resolve => {
            if (savedPosition) {
              return savedPosition;
            } else {
              if (from.meta.saveSrollTop) {
                const top: number =
                  document.documentElement.scrollTop || document.body.scrollTop;
                resolve({ left: 0, top });
              }
            }
          });
        }
      });
    }

    return this;
  }

  private changeMenuToRouter(menus: IMenu[]): RouteRecordRaw {
    const routes: RouteRecordRaw = {
      path: "/backstage",
      name: "backstage",
      component: () => import("@/layouts/backstage/index.vue"),
      meta: {
        title: "后台管理"
      },
      children: []
    };
    routes.children = menus
      .map(r => {
        const { id, title, text, router, link, frame, moda, path, keepAlive } =
          r;
        if (moda === "LINK") {
          return null;
        }
        const isinteral = moda === "ROUTER";
        return {
          path: router,
          name: isinteral ? path : id,
          component: isinteral
            ? modules[`/src/views/${path}/index.vue`]
            : () => import("@/layouts/frame/frameView.vue"),
          meta: {
            title: title || text,
            keepAlive,
            frame,
            link
          }
        };
      })
      .filter(r => r);
    return routes;
  }

  addLoginRouter(routes: RouteRecordRaw) {
    this.addRoutes(routes);
    return this;
  }

  addBackStageRouter(menus: IMenu[]) {
    const record = this.changeMenuToRouter(menus);
    this.addRoutes(record);
  }

  addRoutes(routes: RouteRecordRaw | RouteRecordRaw[]) {
    const record = Array.isArray(routes) ? routes : [routes];
    record.forEach(r => {
      if (this.router.hasRoute(r.name)) {
        this.router.removeRoute(r.name);
      }
      this.router.addRoute(r);
    });
    return this;
  }

  private beforeEach() {
    if (!this.router) {
      throw new Error("请先掉用createRouter初始化router");
    }
    this.router.beforeEach(
      (
        to: RouteLocationNormalized,
        _from: RouteLocationNormalized,
        next: NavigationGuardNext
      ) => {
        NProgress.start();
        this.beforeEvent(to, _from, next);
      }
    );
  }

  beforeEvent(
    _to: RouteLocationNormalized,
    _from: RouteLocationNormalized,
    next: NavigationGuardNext
  ) {
    next();
  }

  private afterEach() {
    if (!this.router) {
      throw new Error("请先掉用createRouter初始化router");
    }
    this.router.afterEach(() => {
      this.afterEvent();
      NProgress.done(true);
    });
  }

  afterEvent() {
    console.log("to, _fromto, _fromto, _from");
  }

  useTo(app: App<Element>) {
    if (this.router) {
      if (!this.isAdd) {
        this.isAdd = true;
        app.use(this.router);
      }
      return this;
    }
    throw new Error("请先掉用createRouter初始化router");
  }

  async isReady() {
    if (this.router) {
      await this.router.isReady();
    }
    return this;
  }
}
